home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-14 | 69.6 KB | 2,041 lines |
-
-
-
-
- PBFILES.DOC
- ─────────────────────────────
- Documentation for PBFILES.ASM
-
-
-
-
-
-
-
-
-
-
- Copyright 1994 Brian McLaughlin
- ────────────────────────────────────────────
- All Rights Reserved
-
-
-
-
-
- TABLE OF CONTENTS
-
- line number
-
- INTRODUCTION ..................................... 83
-
- About MAXLIB For PB ........................... 121
- Packing List .................................. 192
- Requirements for Using PBFILES................. 212
- PBFILES On A Network .......................... 232
- Limited Warranty .............................. 243
-
- HOW TO USE PBFILES
-
- Using $LINK and $INCLUDE ...................... 273
- About File Handles ............................ 316
- About File Pointers ........................... 345
- Example Code .................................. 460
- Handling Errors ............................... 600
- DOS Error Codes ............................... 729
- About DOS STDxxx Devices ...................... 762
- Avoiding Problems with HUGE Arrays ............ 835
-
- PBFILES REFERENCE ................................ 947
-
- ClipF ......................................... 996
- CloseF ........................................ 1035
- EndF% ......................................... 1058
- ErrorCode% .................................... 1092
- FlushF ........................................ 1119
- GetF .......................................... 1149
- GetLineF$ ..................................... 1216
- GetLocF& ...................................... 1274
- GetPtrBase% ................................... 1308
- GetStF ........................................ 1350
- HandleF% ...................................... 1396
- KillF ......................................... 1424
- LoadF ......................................... 1451
- OpenF% ........................................ 1497
- PutF .......................................... 1552
- PutStF ........................................ 1612
- SaveF ......................................... 1650
- SaveLineF ..................................... 1696
- SetAccessCode ................................. 1754
- SetBufferSize ................................. 1798
- SetErrorCode .................................. 1840
- SetLocF ....................................... 1864
- SetPtrBase .................................... 1916
- SizeF& ........................................ 1958
-
- WHY THIS FILE IS COPYRIGHTED ..................... 1987
-
- LIMITED DISTRIBUTION LICENSE ..................... 2012
-
-
-
-
- INTRODUCTION
-
-
- The routines in PBFiles grew out of my frustration with the file
- i/o commands QuickBASIC 4.5. When PowerBASIC 3.0 was released I
- adapted my code for use with that compiler.
-
- With PBFiles you do not need to use ON ERROR to handle file i/o
- errors. Instead, you have complete control over when, where and
- how your program polls for errors.
-
- PBFiles traps critical errors, so your program won't be
- interrupted by the DOS critical error handler and its infamous
- "Abort, Retry, Fail..." message.
-
- With PBFiles you can read to or write from almost any variable
- type or array, with the only limit on the number of bytes you
- can move at a single call being the largest block of addressable
- RAM.
-
- With PBFiles you can read from or write to any segment in
- memory, without the 64K limit of BSAVE and BLOAD and without a
- header being attached to your file. If you are saving video
- RAM, you can put any number of screens in a single file and
- access them in any order.
-
- I have placed the source code for PBFiles (PBFILES.ASM) into the
- public domain, so now you can have this power and simplicity in
- your programs - for free.
-
- Please note that the file you are reading (PBFILES.DOC) is
- copyrighted and can only be reproduced according to the terms
- outlined in LIMITED DISTRIBUTION LICENSE, at the end of this
- file.
-
-
-
-
- ABOUT MAXLIB FOR PB
-
-
- If you like PBFiles, you may be interested in a shareware
- library of routines I have developed, called MAXLIB For PB.
-
- MAXLIB for PB v1.0 consists of two complete sets of routines:
- MAXFiles and MAXArray. Together they give you the first really
- painless way to add EMS memory management to your programs!
-
- Most of the 25 commands in MAXFiles are duplicates of the
- commands in PBFiles, so that your code can be easily translated
- from PBFiles to MAXFiles. MAXFiles speeds up your program's
- disk file access by loading disk files into expanded memory as
- they are opened. From then on, your program will read from and
- write to the file in expanded memory, which is much faster than
- if the file were accessed directly from the disk.
-
- MAXFiles takes advantage of whatever expanded memory is
- available (if any) and will automatically fall back to using
- disk space when expanded memory is exhausted. For that reason,
- programs written using MAXFiles can run on computers with no
- expanded memory, or with very little, or a lot -- all using the
- same few lines of code!
-
- The 16 commands in MAXArray are patterned after the BASIC
- commands used to dimension and manage arrays in conventional
- memory. With MAXArray you can create and manage arrays that are
- much larger than 640K -- right up to the limit of available EMS
- memory, without having to learn all the intricacies of expanded
- memory management.
-
- MAXArray lets you copy entire files or conventional arrays into
- and out of expanded memory using a single line of code! And
- because it has less internal complexity, MAXArray is even faster
- than MAXFiles.
-
- It is my hope that MAXLIB For PB will become widely available
- through normal channels of shareware distribution, such as
- BBSes, CD-ROMs and disk swapping among users. But if you can't
- find a copy, you can order your evaluation copy of MAXLIB for PB
- this way:
-
- 1) Send $5 to cover shipping and handling if you live in the
- USA, or $8 if you live outside the USA. (You must send $US
- funds or a check drawn on a US bank.)
-
- 2) INCLUDE YOUR ADDRESS (!) and whether you want 3.5" or 5.25"
- disks. If you omit the disk size I will send 3.5". All
- disks will be DS/DD.
-
- 3) Be sure to note that you want the PB3 version (other
- versions are planned for other compilers.)
-
- 4) Send all of the above to:
-
- Brian McLaughlin
- MAXLIB for PB Trial Disk
- PO Box 2131
- Lake Oswego, OR 97035
- USA
-
-
- 5) The copy you receive will be for evaluation purposes only.
- Full registration is required before you can distribute any
- programs incorporating MAXLIB For PB.
-
-
-
-
-
- PACKING LIST
-
-
- For this copy of PBFILES.DOC to be legal, you should have ALL of
- the following files (at least):
-
-
- PBFILES.DOC -- the file you are reading
- PBFILES.ASM -- the source code for PBFiles
- PBFILES.OBJ -- the object file assembled from PBFILES.ASM
- PBFILES.BI -- the DECLARE statements for PBFiles
-
-
- If all of these files are not present, then this copy of
- PBFILES.DOC is illegal and it should not be copied or
- distributed. (See the section: LIMITED DISTRIBUTION LICENSE)
-
-
-
-
- REQUIREMENTS FOR USING PBFILES
-
-
- To use PBFiles you will need the file PBFILES.OBJ and the
- compiler PowerBASIC 3.0b or later. I have tested PBFILES with
- PowerBASIC 3.0a and there are bugs in that compiler which make
- PBFILES unstable. PowerBASIC is a trademark of PowerBASIC, Inc.
- of Carmel, California.
-
- An assembler is optional. You do not need to know or understand
- assembly language to use PBFiles.
-
- PBFiles is written in 8086 assembly language, so it will run on
- any 80x86-based DOS computer. PBFiles uses DOS services that
- are present in every version of DOS numbered 2.1 or better.
-
-
-
-
-
- PBFILES ON A NETWORK
-
-
- Although PBFiles provides some support for networks, it has not
- been tested in a networked environment. If you use PBFiles in a
- network, you should test it thoroughly, until you are satisfied
- it is safe.
-
-
-
-
- LIMITED WARRANTY
-
-
- Please read the following warranty carefully:
-
- THIS COPY OF PBFILES (THE "SOFTWARE") IS PROVIDED ON AN "AS IS"
- BASIS. BRIAN MCLAUGHLIN (THE "AUTHOR") DISCLAIMS ALL WARRANTIES
- RELATING TO THE SOFTWARE, WHETHER EXPRESSED OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NEITHER
- THE AUTHOR NOR ANYONE ELSE WHO HAS BEEN INVOLVED IN THE
- CREATION, PRODUCTION, OR DELIVERY OF THE SOFTWARE SHALL BE
- LIABLE FOR ANY INDIRECT, CONSEQUENTIAL, OR INCIDENTAL DAMAGES
- ARISING OUT OF THE USE OR INABILITY TO USE SUCH SOFTWARE, EVEN
- IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGES OR CLAIMS. THE PERSON USING THE SOFTWARE BEARS ALL RISK
- AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE.
-
-
-
-
- HOW TO USE PBFILES
-
-
- This section contains enough information to get you started
- using PBFiles. More detailed information is available in the
- PBFILES REFERENCE section.
-
-
-
- USING $LINK AND $INCLUDE
-
-
- Every program that uses PBFiles must meet a few simple
- requirements: it must make the object file PBFILES.OBJ available
- to the PB compiler, and it must include declarations for all the
- routines it uses from PBFiles.
-
- By far the easiest way to meet these requirements is to add two
- simple lines of code near the beginning of your source code.
- The first line uses the $LINK metacommand to incorporate
- PBFILES.OBJ into your program. You must place this line before
- any executable commands in your source code:
-
-
- $LINK "PBFILES.OBJ"
-
-
- If PBFILES.OBJ is not in the current directory, you must tell PB
- how to find it by including the full path in the the file spec.
- For instance, if it were on a RAM disk designated as your D:
- drive, in a subdirectory named LIB, the full file spec would be:
-
-
- $LINK "D:\LIB\PBFILES.OBJ"
-
-
- You will also need to include a second line near the top of your
- source code:
-
-
- $INCLUDE "PBFILES.BI"
-
-
- PBFILES.BI contains the declarations for all the routines in
- PBFiles. The above line of code above includes those
- declarations in your code. Again, if PBFILES.BI is not in the
- current directory, you will need to let PB know how to find it
- by including the full path in the file spec.
-
-
-
-
- ABOUT FILE HANDLES
-
-
- File handles are a lot like file numbers. In BASIC you are
- asked to give a file a number to identify it. Which can be a
- problem when you don't know what file numbers are already in
- use, so you end up using this sort of code:
-
-
- FNum% = FREEFILE
- OPEN FileName$ FOR BINARY AS FNum%
-
-
- Instead of requiring you to come up with your own file number,
- PBFiles uses the DOS file handle. Whenever DOS opens a file, it
- issues the file a unique file "handle". PBFiles simply passes
- that handle along to your code:
-
-
- Handle% = OpenF%(FileName$)
-
-
- Just as most BASIC file commands want to know a file's number
- instead of its name, most PBFiles commands want to know a file's
- handle, not its name.
-
-
-
-
- ABOUT FILE POINTERS
-
-
- It is possible to program in BASIC without ever learning about
- file pointers. However, PBFiles requires that you understand
- file pointers, so if you are unfamiliar with them, please read
- this section.
-
- NOTE: DOS, PB and PBFiles all consider a file's first byte to be
- byte zero rather than byte 1. Although PBFiles does let you
- choose the one-based convention, this section will use the
- zero-based convention throughout.
-
- Think of a file pointer as an invisible finger pointing at the
- exact byte where PBFiles will begin to read from or write to a
- file. It will move itself as you read (or write), like a finger
- following text on the page of a book. As you stop reading (or
- writing) the finger stops itself one byte beyond the most recent
- byte read (or written).
-
- When a file is first opened the pointer is at the first byte of
- the file: byte zero. If you start writing to a file right after
- opening it, you will start writing at byte zero. And if any
- data is in the file it will be overwritten by the new data,
- starting with byte zero.
-
- Luckily, you can move the pointer anywhere you want, anytime you
- want. For the sake of simplicity, let's suppose you have a file
- that is four bytes long and you want to append some data to the
- end of this file. The four bytes would run from zero to 3:
-
-
- BYTES: 0 1 2 3
- ^
-
- Since you have just opened the file, the pointer (^) is at byte
- zero. Before you can append data to the end of a file, the
- pointer must point one byte beyond the file's last byte. In
- this case the last byte is byte 3, and one byte beyond byte 3 is
- byte 4.
-
- To move a pointer for appending data, first you need to know how
- long the file is. In BASIC you could use LOF, but in PBFiles
- you would use SizeF&, like so:
-
-
- Handle% = OpenF%(FileName$)
- Size& = SizeF&(Handle%)
-
-
- In this case, Size& will equal 4, because our file is four bytes
- long. And, conveniently, the byte that is one byte past the end
- is byte 4. You may move the pointer to byte 4, using SetLocF:
-
-
- Size& = SizeF&(Handle%) 'Size& = 4
- SetLocF Handle%, Size& 'pointer is at byte 4
-
-
- Now our file looks like this:
-
-
- BYTES: 0 1 2 3 (4)
- ^
-
- I put the 4 in parentheses because it really doesn't "belong to"
- our file yet, even though the pointer points there. Now, if we
- write something to our file, no old data will be overwritten.
-
- Now let's write some data to our file and see what happens. To
- write data, you might use PUT in BASIC. In PBFiles you might
- use PutF. This is how you'd write an integer to the file:
-
-
- PutF Handle%, 2&, Variable%
-
-
- This writes 2 bytes to the end of our file, so it looks like
- this:
-
-
- BYTES: 0 1 2 3 4 5 (6)
- ^
-
- Now there are six bytes in our file (0-5) and the pointer has
- moved to byte 6. The pointer moves each time we write OR read
- bytes. It moves exactly one byte forward for every byte we read
- or write.
-
- Those last two sentences are VERY important:
-
- ** The pointer moves each time we write OR read bytes. It moves
- exactly one byte forward for every byte we read or write. **
-
- If you do not know where the pointer is, you can get into big
- trouble. To avoid such trouble you can always ask where the
- pointer is by calling GetLocF&. Just remember that when
- GetLocF& tells you the pointer is at byte 1, it is referring to
- the second byte of the file.
-
- That covers all you need to know about file pointers. All in
- all, file pointers allow you to read or write anywhere you want
- in a file. You can open a file, read a few bytes, jump
- somewhere, write over some other bytes, jump to the end, tack on
- some bytes there, then jump back to the start - all without
- having to close and reopen your file.
-
- You are not required to having same-length records. You are not
- required to start at the front and plow straight to the end.
- You can order your data anyway you like and put it anywhere
- that's convenient, just by jumping the pointer there.
-
-
-
-
- EXAMPLE CODE
-
-
- This example code can be cut and pasted into a separate file and
- compiled inside the PB IDE.
-
- This code makes a temporary file, writes data to it from an
- array, changes one element of the array, writes the old data
- back from the file into the array, and then verifies that the
- changed element has resumed its orginal value. It then opens
- this file (PBFILES.DOC) and reads the first few lines of the
- file, printing them onto the screen.
-
- That's not much. But it shows the general concepts you'll need.
-
-
-
- '*********************** START CODE *******************************
-
- $LINK "PBFILES.OBJ" 'assumes OBJ file in current dir
- $INCLUDE "PBFILES.BI" 'contains the DECLARE statements
- DECLARE SUB HandleError () 'dummy error handler
-
- RANDOMIZE TIMER
- SHARED Handle% 'make this global
-
- PRINT "Filling array..."
- DIM Test%(1 TO 1000) 'make a test array of integers
- FOR X% = 1 TO 1000 'and fill it with values
- Test%(X%) = X% 'from 1 to 1000
- NEXT X%
-
- CLS
- FileName$ = "PBFILES.DAT" 'make a temporary file
- IF LEN(DIR$(FileName$)) THEN KillF FileName$ ' kill any previous
- IF ErrorCode% THEN HandleError 'check for error
-
- IF OpenF%(FileName$) THEN 'open (create) the file
- Handle% = HandleF% 'assign handle variable
- PRINT FileName$; " created." 'report success
- ELSE 'or else
- PRINT "Failed to create file." 'report failure
- HandleError 'and call error SUB
- END IF
-
- Bytes& = 2000& '1000 * 2 bytes
- PRINT FileName$; " length in bytes:"; SizeF&(Handle%)
- IF ErrorCode% THEN HandleError 'check for error
- PRINT "File pointer at"; GetLocF&(Handle%)
- IF ErrorCode% THEN HandleError 'check for error
-
- PRINT
- PRINT "About to write "; Bytes&; " bytes to "; FileName$
- PutF Handle%, Bytes&, Test%(1) 'write 'em, cowboy!
- IF ErrorCode% THEN HandleError 'check for error
-
- FlushF Handle% 'flush the buffers
- IF ErrorCode% THEN HandleError 'check for error
-
- PRINT FileName$; " length in bytes:"; SizeF&(Handle%)
- IF ErrorCode% THEN HandleError 'check for error
-
- PRINT "File pointer at"; GetLocF&(Handle%)
- IF ErrorCode% THEN HandleError 'check for error
-
- 'Let's see if the data stays the same when written back from disk.
-
- RandElem% = RND * 1000
- PRINT
- PRINT "About to select a random array element and change it."
- PRINT "Old value of random element:"; Test%(RandElem%)
-
- Test%(RandElem%) = (RND * 1000) + 1000
- PRINT "New value of random element:"; Test%(RandElem%)
-
- SetLocF Handle%, 0& 'move pointer to byte 0
- IF ErrorCode% THEN HandleError 'check for error
-
- PRINT
- PRINT "About to write original data back from file into array."
- PRINT "Before writing from file, pointer at:"; GetLocF&(Handle%)
-
- GetF Handle%, Bytes&, Test%(1) 'write file to array
- IF ErrorCode% THEN HandleError 'check for error
-
- PRINT "After writing from file, pointer at:"; GetLocF&(Handle%)
- PRINT "Current value of element that was changed:"; Test%(RandElem%)
- PRINT
-
- CloseF Handle%
- IF ErrorCode% THEN HandleError
- PRINT FileName$; " closed."
-
- KillF FileName$
- IF ErrorCode% THEN HandleError
- PRINT FileName$; " deleted."
-
- 'Now let's open PBFILES.DOC and show a few lines of it.
-
- FileName$ = "PBFILES.DOC" 'assume file is in current directory
-
- IF LEN(DIR$(FileName$)) THEN 'try to find the file
- IF OpenF%(FileName$) THEN 'open PBFILES.DOC
- Handle% = HandleF% 'assign handle variable
- ELSE 'or else
- HandleError 'call error SUB
- END IF
- ELSE
- PRINT "Couldn't find PBFILES.DOC. Ending now."
- END
- END IF
-
- LOCATE 24, 1
- PRINT "Press a key to see text from PBFILES.DOC..."
- DO: LOOP UNTIL LEN(INKEY$)
-
- CLS
- FOR X% = 1 TO 22 'print 22 lines
- PRINT GetLineF$(Handle%)
- IF ErrorCode% THEN
- HandleError
- END IF
- NEXT X%
-
- CloseF Handle% 'close PBFILES.DOC
- END
-
- '=================
- SUB HandleError
- '=================
-
- PRINT "An error occured. The error number was: "; ErrorCode%
- PRINT "Aborting program now...."
- END 'ends program
-
- END SUB
- '************************* END CODE ********************************
-
-
-
- HANDLING ERRORS
-
-
- The usual method of error handling in BASIC requires that you
- use some variation of the ON ERROR statement. I have always
- found ON ERROR to be cumbersome, code-bloating and difficult to
- program. Even PowerBASIC's own manual (p.288) suggests that you
- consider using a third party library.
-
- I think you will find the error trapping in PBFiles to be simple
- to use. Whenever an error takes place (including critical
- errors), the PBFiles routine that was running at the time of the
- error will store the error code in an internal variable and
- return directly to your program.
-
- Your program must test the value of this error code variable in
- order to find out whether an error has occured. PBFiles has a
- routine called ErrorCode% for reporting the value of the
- internal error code variable.
-
- The process of testing the value of an error code variable is
- called polling.
-
-
- Handle% = OpenF%(FileName$) IF ErrorCode% THEN CALL
- HandleError...
-
-
- In the above example, the code polls for an error directly after
- opening a file, and if an error is reported the code calls a SUB
- named HandleError.
-
- You can poll for errors as often or as seldom as you think
- necessary. If an error takes place in one routine and your
- program calls several more routines before polling for an error,
- the value of the error code variable will report the most recent
- error to take place, if any.
-
- The internal error code variable is initialized to zero only
- once, at the beginning of your program. The value of this
- variable will remain zero so long as no error takes place.
-
- However, when the first error takes place, the value of this
- variable will change to reflect the error code, and it will
- remain unchanged until one of two things intervenes to change
- its value:
-
- 1) another (different) error takes place, or
- 2) your program resets the value, using SetErrorCode.
-
-
- SetErrorCode is similar to the function ERROR in BASIC. You may
- use it to clear the error code variable back to zero like this:
-
-
- SetErrorCode 0
-
-
- SetErrorCode may also be used to simulate errors (for example,
- during the testing of your error handler) by passing non-zero
- values corresponding to error codes. The corresponding
- error-reporting routine will report these values back to your
- program as errors:
-
-
- SetErrorCode 2
- IF ErrorCode% THEN .... 'ErrorCode% always returns 2 here
-
-
- A list of error codes and what they mean can be found in the
- section DOS ERROR CODES, below. You may also encounter one
- non-standard error code: -1. The -1 indicates that GetLineF$
- was unable to allocate a string to use as a buffer.
-
- Because PBFiles requires your program to poll for errors, the
- error handling in PBFiles is roughly the same as ON ERROR RESUME
- NEXT used with ERR, in this fashion:
-
-
- ON ERROR RESUME NEXT 'if error happens keep going
- .
- .
- OPEN FileName$ FOR BINARY AS #1 'an error might happen here
- IF ERR THEN 'see if an error occured
- CALL ErrorHandler 'if so, go handle it
-
-
-
- The equivalent code in PBFiles would be:
-
-
- FileNum% = OpenF%(FileName$) 'an error might happen here
- IF ErrorCode% THEN 'see if an error occured
- CALL ErrorHandler 'if so, go handle it
-
-
- It is important to realize that PBFiles won't handle errors for
- you. What PBFiles will do is trap the error and let you know
- which error it was. To handle errors actively, you must use an
- error handler in your program.
-
- The writing of an error handler is not difficult to understand.
- A typical error handler will consist of a SELECT CASE structure
- in which the various errors you anticipate are grouped according
- to the various messages you want to display or actions you want
- your program to take.
-
-
- SELECT CASE ErrorCode%
- CASE 2
- PRINT "File not found."
- CASE 3
- PRINT "Path not found."
- CASE 4
- .
- .
- CASE ELSE
- PRINT "Unknown error. Error code:"; ErrorCode%
- END SELECT
-
-
- At the very least, an error handler reports error codes along
- with descriptive messages. A more comprehensive error handler
- will allow your program the chance to resolve the error, or to
- shut down gracefully and save your data if possible.
-
-
-
-
- DOS ERROR CODES
-
-
- The following list of DOS error codes isn't exhaustive. It
- includes the most likely file access errors in a single-user,
- non-networked environment. Consult a DOS reference for a
- complete listing of DOS errors.
-
- ErrorCode% may also report one non-standard error code: -1.
- This error code is reported when GetLineF$ is unable to allocate
- a string to use as an internal buffer.
-
-
- 2 File not found
- 3 Path not found
- 4 No file handles available
- 5 Access denied
- 6 Invalid handle
- 8 Insufficient memory
- 15 Invalid drive
- 19 Write-protected disk
- 21 Drive not ready
- 25 Seek error
- 26 Unknown media type
- 27 Disk sector not found
- 28 Out of paper (when writing to STDPRN)
- 29 Write fault
- 30 Read fault
- 31 General failure
-
-
-
-
- ABOUT DOS STDXXX DEVICES
-
-
- Each time your computer boots, DOS opens a set of 5 handles,
- numbered 0-4. These handles are assigned to 5 standard devices.
- DOS uses these handles to access the devices for its own input
- and output. They are:
-
-
- Device: Handle: Initialized as:
- ------- ------- ---------------
- STDIN 0 Keyboard
- STDOUT 1 Screen
- STDERR 2 Screen
- STDAUX 3 Com port 1
- STDPRN 4 Printer (LPT1)
-
-
-
- Because PBFiles is handle-based, you can take advantage of these
- STDxxx devices by passing their handles to the various PBFiles
- routines.
-
- You should realize that using these DOS devices can be a crude
- method of input and output. Only in a few situations will there
- be any advantage to using them, and in many cases there will be
- disadvantages. Most especially, I do not recommend that you try
- to use STDAUX and PBFiles as a substitute for the built-in
- communications capabilities of PowerBASIC.
-
- Two examples come quickly to mind where a STDxxx device has an
- advantage over using BASIC's own commands. One is where you
- want to direct your program's output through the ANSI.SYS device
- driver. The other is when you want to be able to redirect or
- pipe input or output from the command line.
-
- To output a string to the screen through DOS services, you could
- use BASIC code similar to this:
-
-
- OPEN "CONS:" FOR OUTPUT AS #1
- OutPut$ = "This will reach the screen via DOS."
- PRINT #1, OutPut$
-
-
- The PBFiles (rough) equivalent would be this:
-
-
- %STDOUT = 1
- OutPut$ = "This will reach the screen via DOS."
- PutStF %STDOUT, OutPut$ + CHR$(13,10)
-
-
- In this example, OutPut$ would be (normally) be written to the
- screen by DOS. If DOS redirection were in effect, the string
- would be output to the device or file indicated on the command
- line, instead of to the screen. If OutPut$ included ANSI escape
- codes, they could be intercepted and acted upon by ANSI.SYS.
-
- Most of the routines in PBFiles will accept STDxxx handles, with
- two exceptions. CloseF will not close a handle numbered 0-4,
- and GetLineF$, because of its internal buffer and internal
- pointer, cannot accept a DOS device handle, either.
-
- Overall, if you require DOS redirection in your programs, you
- should be able to manage it, using just the routines in PBFiles.
- But it may take some experimentation. For more information
- about DOS STDxxx devices, you should consult a good DOS
- reference.
-
-
-
-
- AVOIDING PROBLEMS WITH HUGE ARRAYS
-
-
- Using the HUGE keyword lets you to dimension arrays that are
- larger than a single 64K segment. To accomplish this the
- PowerBASIC compiler must know when the current array segment
- contains all the elements it can hold, so it can skip ahead to
- the first byte of the next 64K segment, where it locates the
- next element.
-
- As an example, let's imagine you want to dimension an array of
- 1000 fixed length strings, where each string is 80 bytes long.
- This makes an array 80000 bytes long. Obviously this is greater
- than one 64K segment, so it must be dimensioned as a HUGE array:
-
-
- DIM HUGE FixedStrings(1 TO 1000) AS STRING * 80
-
-
- The compiler can put 819 elements of 80 bytes each into the
- first 64K segment. At that point it has used up 65520 bytes of
- the segment and it only has 16 bytes left in that segment.
- That's not enough to hold a complete element, so the compiler
- will insert 16 unused bytes into the array at that point. This
- permits element 820 to start at a new 64K segment boundary.
-
- In the BASIC environment, placing a discontinuity like this into
- the data in HUGE arrays is not a problem, because array elements
- are always accessed individually in BASIC. PBFiles, however,
- has two routines that allow you to access entire arrays or
- portions of arrays all at once, GetF and PutF.
-
- The difficulty arises because these commands read data as a
- continuous series of bytes, while the compiler may be storing
- the data in a discontinuous series of bytes. In our example
- array, a discontinuity of 16 bytes occurs between elements 819
- and 820.
-
- Now let's say you want to save a copy of this HUGE array into a
- file, using PutF. It might seem natural to write code like
- this:
-
-
- FileName$ = "FIXSTRNG.DAT"
- SaveHandle% = OpenF%(FileName$) ' open a file to save into
-
- Bytes& = CLNG(80 * 1000) ' calculate bytes to save
- PutF SaveHandle%, Bytes&, FixedStrings(1) 'save them
-
-
- The problem comes in the third line, in calculating how many
- bytes we need to write into the file. Yes, there are 80000
- bytes of data to be read, but because of the 16 unused bytes
- that were inserted at the end of the first 64K segment, those
- 80000 bytes of data are stored across 80016 bytes of memory!
-
- The example code shown above will not work, because PutF is not
- smart enough to skip over the 16 bytes of non-data inserted into
- the array. Instead it will read those 16 bytes of padding into
- the file and it will stop before it reads the final 16 bytes of
- data.
-
- The easy way to work around this problem is to read each element
- individually, in a loop, and write each one to the file:
-
-
- FileName$ = "FIXSTRNG.DAT"
- SaveHandle% = OpenF%(FileName$) ' open a file to save into
-
- Bytes& = 80& ' read one element at a time
- FOR X% = 1 TO 1000
- PutF SaveHandle%, Bytes&, FixedStrings(X%)
- NEXT X%
-
-
- This code works because the correct address of each element will
- be passed to PutF and the 16 bytes of padding after element 819
- will be skipped over, automatically. PowerBASIC will pass the
- correct address for element 819, then the correct address for
- element 820.
-
- This is not the fastest solution possible, but it is by far the
- simplest. It is not the fastest because it requires your
- program to access the disk 1000 times, instead of once.
-
- Another possible work around is to make the disk file 80016
- bytes long, so it contains all the data, along with the gap in
- the data. Then you could load the resulting file directly into
- a HUGE array having the same dimensions as the original array,
- using GetF, because an identical array will have the same gap in
- the data, located in the same place.
-
- This last approach is fairly simple and and also the fastest,
- since it uses the fewest disk reads or writes. However, it is
- also the least flexible approach, since it requires you to load
- the file into an array that is identically dimensioned to the
- original array.
-
- Remember, this problem only applies to HUGE arrays where the
- element size is not a power of two. The only PowerBASIC arrays
- that might fit that description would be arrays of TYPE
- variables, or fixed-length strings, or extended precision
- numbers or BCD floating point numbers. The first two of those
- variable types can have almost any length. The last two have a
- fixed length of 10 bytes each.
-
-
- **************************************************************
-
-
-
-
- PBFILES REFERENCE
-
-
-
- The following is a list of PBFiles routines along with their
- closest counterparts in PowerBASIC:
-
-
- OpenF% ................ OPEN (...FOR BINARY)
- SetAccessCode ......... ACCESS LOCK/UNLOCK/READ/WRITE, etc.
- CloseF ................ CLOSE# (close one open file)
- PutF .................. PUT (file statement)
- GetF .................. GET (file statement)
- PutStF ................ PUT$
- GetStF ................ GET$
- SaveF ................. BSAVE
- LoadF ................. BLOAD
- GetLineF$ ............. LINE INPUT# (file statement)
- EndF% ................. EOF
- GetLocF& .............. SEEK (as a function)
- SetLocF ............... SEEK (as a statement)
- SizeF& ................ LOF
- KillF ................. KILL
- FlushF ................ FLUSH
- ErrorCode% ............ ERR
- SetErrorCode .......... ERROR
- SetPtrBase ............ OPTION BASE
-
-
- PBFiles also includes the following commands that have no exact
- equivalent in BASIC:
-
-
- ClipF ................. truncates a file
- GetPtrBase% ........... returns value set by SetPtrBase
- HandleF% .............. returns latest handle opened
- SaveLineF ............. allows GetLineF to read multiple files
- SetBufferSize ......... controls size of buffer for GetLineF
-
-
- NOTE: Although the routines in PBFiles include some support for
- networks, they have not been tested in a networked environment.
- If you intend to use PBFiles on a network, you should test your
- code thoroughly to ensure it is network safe.
-
-
-
-
-
- ClipF
- -----------------------------------------------------------------
-
- DECLARE SUB ClipF (Handle%, NewSize&)
-
- Parameters: Handle% = handle of file to truncate
- NewSize& = new size of file, in bytes, as long integer
-
-
-
- ClipF lets you truncate an opened file to the size you specify:
-
-
- ClipF Handle%, 3500&
-
-
- The above code shortens the file designated by Handle% to a
- length of 3500 bytes, assuming the file was more than 3500 bytes
- long.
-
- After a call to ClipF the file pointer will point to the first
- byte immediately following the new end byte of the file. In the
- example above (assuming a zero-based convention for counting
- bytes), the first byte of the file would be byte zero, the final
- byte of the file would be byte 3499 and the pointer would be at
- byte 3500.
-
- IMPORTANT: If NewSize& exceeds the current file size then ClipF
- will move the pointer one byte beyond the current end byte of
- the file, but the file will remain the same size.
-
- For more information about file pointers, see ABOUT FILE
- POINTERS.
-
- See also SetLocF.
-
-
-
-
- CloseF
- -----------------------------------------------------------------
-
- DECLARE SUB CloseF (Handle%)
-
- Parameters: Handle% = handle of file to close
-
-
-
- CloseF is a substitute for CLOSE #FileNum in BASIC. It closes
- one file opened by OpenF%.
-
-
- CloseF Handle%
-
-
- The above code closes the file designated by Handle%. CloseF
- will ignore any attempts to close a handle numbered 0-4. Those
- handles are reserved by DOS and closing them would be a mistake.
-
-
-
-
- EndF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION EndF% ()
-
- Parameters: none
-
-
- EndF% is a substitute for EOF. It works in conjunction with
- GetLineF$ only. While GetLineF$ is processing a text file and
- bytes remain to be read, EndF% returns a zero. When GetLineF$
- reaches the end of the file and no more bytes remain to be read,
- EndF% returns -1.
-
-
- DO
- X% = X% + 1
- Array$(X%) = GetLineF$(Handle%)
- LOOP UNTIL EndF% OR ErrorCode%
-
-
- The above code loads a variable length string array with lines
- of text from the file designated by Handle%. The loop will
- iterate until the end of the file is reached, or an error
- occurs.
-
- EndF% will not report the end of a file when a CHR$(26) is
- encountered in a file.
-
- See also GetLineF$.
-
-
-
-
- ErrorCode
- -----------------------------------------------------------------
-
- DECLARE FUNCTION ErrorCode% ()
-
- Parameters: none
-
-
- When an error occurs during any of the PBFiles routines, the
- error is trapped (no action is taken by DOS or BASIC) and the
- error code is stored in an internal variable. This includes
- critical errors. The current content of that variable is
- returned by ErrorCode%.
-
-
- IF ErrorCode% = 2 THEN PRINT "File not found!"
-
-
- For more information see HANDLING ERRORS and the section DOS
- ERROR CODES.
-
- See also SetErrorCode.
-
-
-
-
-
- FlushF
- -----------------------------------------------------------------
-
- DECLARE SUB FlushF (Handle%)
-
- Parameters: Handle% = handle of the file to flush to disk
-
-
-
- FlushF is a substitute for FLUSH. FlushF causes the contents of
- the file buffers (maintained by DOS) to be written to disk.
- Files that have been flushed remain open.
-
-
- FlushF Handle%
-
-
- The above code flushes the complete contents of the file
- designated by Handle% onto disk.
-
- Flushing is important if you are working with highly valuable
- data, because any data that is not fully written to disk is
- vulnerable to loss if something disrupts the operation of the
- computer running your program.
-
- See also CloseF.
-
-
-
-
- GetF
- -----------------------------------------------------------------
-
- DECLARE SUB GetF (Handle%, Bytes&, ToVariable AS ANY)
-
- Parameters: Handle% = the handle of the file to read from
- Bytes& = number of bytes to read
- ToVariable = the variable to read the data into
-
-
-
- GetF resembles GET, but is more powerful. It allows you to read
- Bytes& number of bytes from a file into a variable or into an
- array. You must specify the handle of the file to read from,
- the number of bytes to read, and the variable to read into. If
- you are reading into an array, you need to specify the first
- element of the range to be read into:
-
-
- GetF Handle%, 4000&, Arry&(100)
-
-
- The above example reads 4000 bytes from the file specified by
- Handle% into Arry&() starting at element 100.
-
- IMPORTANT: Before using GetF with HUGE arrays, read the section
- AVOIDING PROBLEMS WITH HUGE ARRAYS.
-
- GetF always reads from the file starting at the position of the
- file pointer. GetF will automatically advance the file pointer
- one byte forward for each byte it reads. It is up to you to
- make certain the file pointer is where you want it to be before
- calling GetF.
-
- If you tell GetF to write more bytes than the target variable or
- array can hold, it will overwrite whatever lies beyond the end
- of your variable or array. If you tell it to write too few
- bytes, whatever "garbage" was in that area of RAM won't be fully
- overwritten. It is your responsibility to calculate the correct
- number of bytes.
-
- If you try to read from a file when the file pointer is located
- beyond its end, then GetF will simply return with no action
- taken and no error code. If you try to read more bytes than are
- available between the pointer and the end byte of the file, GetF
- will read as far as the end byte of the file and stop.
-
- If Bytes& is less than or equal to zero, GetF will return
- without taking any action. No error will be reported.
-
- NOTE: When a parameter is declared AS ANY it must be passed as a
- variable. If you pass an equation, constant or literal value,
- the compiler will report Error 426: Variable expected.
-
- GetF can write to both variables or arrays of the following
- types: fixed-length strings, numeric variables, and TYPE
- variables.
-
- GetF is NOT suitable for reading from files into variable length
- strings, flex strings or arrays of such strings. For these
- strings you would use GetStF or GetLineF$.
-
- See also PutF.
-
-
-
-
- GetLineF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION GetLineF$ (Handle%)
-
- Parameters: Handle% = the handle of the file to read from
-
-
-
- GetLineF$ is a substitute for LINE INPUT#. It simplifies the
- task of reading ASCII text files one line at time.
-
-
- TextLine$ = GetLineF$(Handle%)
-
-
- The above code returns one line of text from the file designated
- by Handle%. The line of text starts with the character at the
- current file pointer and includes all characters up to but not
- including the first carriage return character, or CHR$(13). If
- the first character encountered is a CHR$(13), GetLineF$ returns
- a null string.
-
- The longest string GetLineF$ may return is 256 bytes. When
- GetLineF$ does not encounter a CHR$(13) within the first 256
- characters it simply returns those 256 characters.
-
- GetLineF$ allocates a string to use as an internal buffer. The
- default size of this buffer is 8174 bytes. When GetLineF$
- detects the end of a file, it sets the value reported by EndF%
- to -1 and it deallocates its buffer.
-
- If GetLineF$ fails to allocate a string to use as a buffer, it
- will return a non-standard error code of -1. One common way for
- the buffer allocation to fail is if your code uses the
- metacommand $STRING to set a string segment size smaller than
- 8K. The default buffer size of 8174 bytes requires an 8K string
- segment (or larger).
-
- If buffer allocation fails, or if you require a larger or
- smaller buffer for other reasons, you may change the size of the
- buffer. See SetBufferSize for more details.
-
- Buffering requires GetLineF$ to maintain its own internal
- pointer, which will rarely agree with the "regular" file
- pointer. For that reason, if you use GetLineF$ to read from
- more than one file at once, you may need to use SaveLineF. For
- more details, see SaveLineF.
-
- GetLineF$ will not accept a handle for a DOS STDxx device (0-4).
- If you call GetLineF$ with such a handle, it will simply return
- a null string and report an "invalid handle" error (6).
-
- See also EndF%, GetStF.
-
-
-
-
- GetLocF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION GetLocF& (Handle%)
-
- Parameters: Handle% = handle of file in which to find pointer
-
-
-
- GetLocF& is a substitute for the function form of SEEK. It
- returns a long integer representing the present position of the
- file pointer within the file specified by Handle%:
-
-
- PtrLoc& = GetLocF&(Handle%)
-
-
- The above code returns the current position of the file pointer
- in the file designated by Handle%.
-
- By default, the file is assumed to start at byte 0 (zero). This
- default may be changed to start at byte 1 by using the command
- SetPtrBase. See SetPtrBase or GetPtrBase for further details.
-
- If an error occurs during a call to GetLocF&, it returns a zero.
- Normally, zero is a legal file pointer location. To determine
- with certainty whether an error has occured you must call
- ErrorCode%.
-
- See also SetLocF.
-
-
-
-
- GetPtrBase
- -----------------------------------------------------------------
-
- DECLARE FUNCTION GetPtrBase% ()
-
- Parameters: none
-
-
-
- GetPtrBase% returns the base value used by GetLocF& and SetLocF:
-
-
- Base% = GetPtrBase%
-
-
- The above code returns the current pointer base value. The
- default value is zero, but you may change the value to 1, by
- calling SetPtrBase.
-
- Normally, DOS defines the first byte of a file as byte 0 (zero).
- However, when Microsoft introduced BINARY file handling into
- BASIC, it chose to treat the first byte of a file as byte 1. To
- accomodate code written for this convention, PBFiles includes
- the commands SetPtrBase and GetPtrBase%.
-
- When GetPtrBase% returns zero, PBFiles is acting under the
- zero-based (DOS) convention. Under this convention, when the
- pointer is at the second byte of a file, GetLocF& will return 1,
- and if you want to set the pointer to the second byte you would
- use SetLocF 1.
-
- When GetPtrBase% returns 1, PBFiles is acting under the
- one-based (Microsoft BASIC) convention. Under this convention,
- when the pointer is at the second byte of a file, GetLocF& will
- return 2, and to set the pointer to the second byte you would
- use SetLocF 2.
-
- See also SetPtrBase.
-
-
-
-
- GetStF
- -----------------------------------------------------------------
-
- DECLARE SUB GetStF (Handle%, ToString AS ANY)
-
- Parameters: Handle% = handle of the file to read from
- ToString = variable or flex string to read data into
-
-
-
- GetStF is a substitute for GET$. It lets you read from a file
- into a variable length string or flex string. Before calling
- GetStF the string must be initialized to the length you want.
- The length of the string determines the number of bytes GetStF
- will read from the file into the string:
-
-
- Target$ = SPACE$(100)
- GetStF Handle%, Target$
-
-
- In the above code, 100 bytes would be read from the file
- specified by Handle% into Target$. The file would be read
- beginning at the current position of the file pointer. GetStF
- will advance the file pointer one byte for each byte read.
-
- If you try to read from a file when the file pointer is located
- beyond its end, then GetStF will simply return with no action
- taken and no error code. If you try to read more bytes than are
- available between the pointer and the end byte of the file,
- GetStF will read as far as the end byte of the file and stop.
-
- NOTE: When a parameter is declared AS ANY it must be passed as a
- variable. If you pass an equation, constant or literal value,
- the compiler will report Error 426: Variable expected.
-
- If you want your program to read an ASCII text file (one which
- uses a carriage return and linefeed to delimit each line of
- text) you will probably want to use GetLineF$, rather than
- GetStF.
-
- See also PutStF.
-
-
-
-
- HandleF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION HandleF% ()
-
- Parameters: none
-
-
- HandleF% returns the handle of the file most recently opened by
- OpenF%. Among other things it allows you to use the following
- alternate logic when opening a file:
-
-
- IF OpenF%(FileSpec$) THEN
- Handle% = HandleF% 'get the handle for FileSpec$
- ELSE
- Call ErrorHandler
- END IF
-
-
- It is not recommended that you use HandleF% as a substitute for
- a file handle variable.
-
- See also OpenF.
-
-
-
-
- KillF
- -----------------------------------------------------------------
-
- DECLARE SUB KillF (FileSpec$)
-
- Parameters: FileSpec$ = name of the file to kill (delete)
-
-
-
- KillF is a substitute for KILL. It accepts a file name, which
- may be up to 64 characters long and include a drive and
- subdirectory path, but not wildcard characters:
-
-
- FileName$ = "D:\PATH\FILENAME.EXT" 'no wildcards
- KillF FileName$ 'delete the file
-
-
- Do not try to kill a file when it is open. Close it first using
- CloseF. If you kill a file when it is open PBFiles will not
- report an error, but you may end up with a mess, possibly
- including cross-linked files that must be repaired by the DOS
- CHKDSK command.
-
-
-
-
- LoadF
- -----------------------------------------------------------------
-
- DECLARE SUB LoadF (Handle%, Bytes&, ToSegment??)
-
- Parameters: Handle% = handle of the file to load data from
- Bytes& = number of bytes to load
- ToSegment?? = segment at which to load the data
-
-
-
- LoadF resembles BLOAD, but is more powerful. Before you can
- load a file with LoadF you must open it using OpenF%. You pass
- LoadF the handle of an opened file, the number of bytes to load,
- and the segment address where you want them loaded. It assumes
- an offset of zero.
-
-
- LoadF Handle%, 4000&, &HB800
-
-
- The above code loads 4000 bytes from the file designated by
- Handle% starting at the address &HB800:0000 (page zero of a
- color monitor's video RAM, in text mode).
-
- You may set the file pointer wherever you wish before calling
- LoadF, and therefore may read from the file at any point. This
- allows you to have more than one screen saved in a single file.
-
- If you try to read from the file when the pointer is located
- beyond its end, then LoadF will simply return with no action
- taken and no error code. If you try to read more bytes than are
- available between the pointer and the end byte of the file,
- LoadF will read as far as the end byte of the file and stop.
-
- If Bytes& is less than or equal to zero, LoadF will return
- without taking any action. No error will be reported.
-
- Unlike BLOAD, LoadF will not close the file for you. You must
- close it using CloseF.
-
- See also SaveF.
-
-
-
-
- OpenF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION OpenF% (FileSpec$)
-
- Parameters: FileSpec$ = name of the file to open or create
-
-
-
- OpenF% is a substitute for OPEN FOR BINARY. It accepts a
- FileName$ up to 64 characters long, which can include a drive
- and path, but not wildcard characters. OpenF% opens the file
- named and returns the handle that you must use to access that
- file, or a zero if there was an error:
-
-
- FileName$ = "D:\PATH\FILENAME.EXT" 'no wildcards allowed
- Handle% = OpenF%(FileName$)
-
-
- When OpenF% opens a file, it sets the file access code according
- to an internal variable. This variable defaults to the code for
- read-write access and network compatibility mode, but it may be
- changed by making a call to SetAccessCode.
-
- If OpenF% can't find FileName$, it creates a zero-length, normal
- attribute file of that name. Created files are opened using the
- current access code. This requires OpenF% to create the file
- first without the access code, close it and then immediately
- reopen it using the access code. An access code is not the same
- as a file attribute.
-
- When a file is first opened the file pointer always points to
- the first byte of the file. Normally, the first byte is
- considered to be byte 0 (zero). PBFiles also lets you regard
- this byte as byte 1. For more information, see SetPtrBase and
- GetPtrBase%.
-
- If an error occurs during a call to OpenF%, it returns a zero
- rather than a file handle. Zero is a valid handle, but it is
- reserved by DOS for STDIN. If OpenF% returns a zero, don't use
- it! Instead, call ErrorCode%.
-
- When FileName$ is null or more than 64 characters, then OpenF%
- treats these conditions as "file not found" errors.
-
- If FileName$ includes wildcard characters (?*) then your program
- will crash! Your program must trap this error before calling
- OpenF%.
-
- See also CloseF.
-
-
-
-
- PutF
- -----------------------------------------------------------------
-
- DECLARE SUB PutF (Handle%, Bytes&, FromVariable AS ANY)
-
- Parameters: Handle% = the handle of the file to write to
- Bytes& = number of bytes to write
- FromVariable = the variable to write the data from
-
-
-
- PutF resembles PUT, but is more powerful. It allows you to
- write Bytes& number of bytes from a variable or an array to a
- disk file. You pass PutF the handle of the file to write to,
- the number of bytes to write and the variable to be written
- from. If you are writing from an array, pass PutF the first
- element of the range to be written from:
-
-
- PutF Handle%, 4000&, Arry&(100)
-
-
- The above code writes 4000 bytes from Arry&(), starting at
- element 100, into the file specified by Handle%. PutF will
- write to the file starting at the location of the file pointer.
- The file pointer will advance one byte for each byte written.
-
- IMPORTANT: Before using PutF with HUGE arrays, read the section
- AVOIDING PROBLEMS WITH HUGE ARRAYS.
-
- If the file pointer is anywhere but the end of the file, the
- previous contents of the file will be overwritten as PutF writes
- the new bytes to those locations. It is up to you to make
- certain the file pointer is pointing where you want it, before
- calling PutF.
-
- PutF will ignore any attempt to write zero bytes. This is
- because writing zero bytes has the (sometimes traumatic) effect
- of truncating a disk file. If you desire this effect, see
- ClipF.
-
- If Bytes& is less than or equal to zero, PutF will return
- without taking any action. No error will be reported.
-
- NOTE: When a parameter is declared AS ANY it must be passed as a
- variable. If you pass an equation, constant or literal value,
- the compiler will report Error 426: Variable expected.
-
- PutF can write variables or arrays of the following types:
- fixed-length strings, numeric variables or TYPE variables.
-
- PutF is NOT suitable for use with variable length strings, flex
- strings, or arrays of such strings. Instead, see PutStF.
-
- See also GetF.
-
-
-
-
-
- PutStF
- -----------------------------------------------------------------
-
- DECLARE SUB PutStF (Handle%, FromString AS ANY)
-
- Parameters: Handle% = handle of the file to write to
- FromString = string to write data from
-
-
-
- PutStF is a substitute for PUT$. It allows you to write a
- variable length string or flex string to a file:
-
-
- St$ = "This is a test."
- PutStF Handle%, St$
-
-
- The above code writes St$ to the file designated by Handle%.
- The string will be written starting at the current position of
- the file pointer. PutStF will advance the file pointer one byte
- for each byte written.
-
- If the file pointer is anywhere but the end of the file, the
- previous contents of the file will be overwritten as PutStF
- writes the new bytes to those locations. It is up to you to
- make certain the file pointer is pointing where you want it,
- before calling PutStF.
-
- NOTE: When a parameter is declared AS ANY it must be passed as a
- variable. If you pass an equation, constant or literal value,
- the compiler will report Error 426: Variable expected.
-
- See also GetStF.
-
-
-
-
- SaveF
- -----------------------------------------------------------------
-
- DECLARE SUB SaveF (Handle%, Bytes&, FromSegment??)
-
- Parameters: Handle% = handle of the file to write to
- Bytes& = number of bytes to write
- FromSegment?? = segment to save data from
-
-
-
- SaveF resembles BSAVE, but is more powerful. It allows you to
- read from a memory location, such as video memory, directly into
- a file. Notice that SaveF only lets you to pass the segment
- portion of the address from which you want data saved. It
- assumes an offset of zero.
-
-
- SaveF Handle%, 4000&, &HB800
-
-
- In the above code, the 4000 bytes starting at &HB800:0000 (page
- zero of a color monitor's video RAM in text mode) will be
- written to the file designated by Handle%, starting at the
- current position of the file pointer.
-
- Before you can save to a file using SaveF, you must open the
- file using OpenF%. Also, SaveF will not close the file for you.
- You must close the file seperately, using CloseF, when you are
- done with it.
-
- You may use SaveF to write more than 64K bytes at once. Also,
- you may append data onto the end of an existing file, so you may
- have as many screens full of information as you wish in a single
- file.
-
- If Bytes& is less than or equal to zero, SaveF will return
- without taking any action. No error will be reported.
-
- SaveF does NOT add a header to your files, as BSAVE does.
-
- See also LoadF.
-
-
-
-
- SaveLineF
- -----------------------------------------------------------------
-
- DECLARE SUB SaveLineF ()
-
- Parameters: none
-
-
-
- SaveLineF resets the DOS file pointer of the file most recently
- read by GetLineF$ to match the internal file pointer maintained
- by GetLineF$. SaveLineF is only needed under the following
- conditions:
-
- 1) GetLineF$ has not finished reading file A to the end, and
- 2) you must use GetLineF$ to read from a second file B, and
- 3) you must return later to file A at the point you left off.
-
- Whenever these three conditions exist, you must call SaveLineF
- after your latest read from file A and before reading from file
- B, as in the following example:
-
-
- DO
- INCR LineCount%
-
- LineA$ = GetLineF$(A%)
- SaveLineF
- EndA% = EndF%
- LineB$ = GetLineF$(B%)
- SaveLineF
- EndB% = EndF%
-
- IF LineA$ <> LineB$ THEN
- PRINT "Lines"; LineCount%; " in A and B don't match."
- END IF
-
- LOOP UNTIL EndA% OR EndB%
-
-
- SaveLineF always resets the pointer of the file whose handle was
- last passed to GetLineF$. If you call SaveLineF prior to your
- first call to GetLineF$, it will cause an "invalid handle"
- error. If you have closed the file most recently read by
- GetLineF$, you will also get the same error.
-
- NOTE: Alternating line-by-line between files, as in the example
- above, causes GetLineF$ to repeatedly empty and refill its
- buffer, causing it to slow down significantly. It would be much
- faster to use GetLineF$ to read each file into its own array and
- then to compare the lines afterward.
-
- See also GetLineF.
-
-
-
-
-
- SetAccessCode
- -----------------------------------------------------------------
-
- DECLARE SUB SetAccessCode (AccessCode%)
-
- Parameters: AccessCode% = access code to use in opening files
-
-
-
- SetAccessCode sets the file access code used by OpenF% when
- opening files:
-
-
- SetAccessCode 0
- Handle% = OpenF%(FileName$)
-
-
- The above code opens FileName$ with a read-only access code.
- This is not the same as giving the file a read-only attribute.
- When you set a new access code using SetAccessCode, all
- subsequent calls to OpenF% will use the new access code.
-
- These BASIC commands are equivalent to the following access
- codes:
-
-
- ACCESS READ WRITE ... 2
- ACCESS READ ....... 0
- ACCESS WRITE ....... 1
- ACCESS READ SHARED ... 64
- LOCK READ ....... 50
- LOCK WRITE ....... 34
-
-
- IMPORTANT: PBFiles has not been tested in a networked
- environment. If you use PBFiles in a network, you should test
- it until you are satisfied it is safe.
-
- For more complete information about access codes, consult a DOS
- reference.
-
-
-
-
- SetBufferSize
- -----------------------------------------------------------------
-
- DECLARE SUB SetBufferSize (Bytes%)
-
- Parameters: Bytes% = number of bytes to use for buffer
-
-
-
- SetBufferSize lets you change the size of the buffer allocated
- by GetLineF$. The default buffer size is 8174 bytes.
-
-
- SetBufferSize 5000
-
-
- The example above sets the buffer size to 5000 bytes.
-
- If you try to set the buffer size above 32750 bytes or below
- 1006 bytes, SetBufferSize will round the buffer size up or down
- to match the nearest of these limits.
-
- Because the buffer allocated by GetLineF$ is a string, it is
- affected by the string segment size set by $STRING. The largest
- string that can be allocated within a string segment is the size
- of the segment minus 18 bytes.
-
- For example, if the example code above were preceeded by the
- metacommand $STRING 4, the buffer of 5000 bytes would not fit
- inside the 4K string segment, causing GetLineF$ to fail. You
- would need to set the buffer size to between 4078 and 1006 bytes
- before your first call to GetLineF$ to compensate for the
- $STRING 4 statement.
-
- When GetLineF$ fails to allocate a buffer string, it returns the
- non-standard error code -1.
-
- See also GetLineF.
-
-
-
-
- SetErrorCode
- -----------------------------------------------------------------
-
- DECLARE SUB SetErrorCode (ErrorCode%)
-
- Parameters: ErrorCode% = value to place into internal error code
-
-
-
- SetErrorCode allows you to reset the error code reported by
- ErrorCode% to any integer value:
-
-
- SetErrorCode 2 'set the new error code
- PRINT ErrorCode% 'will always print "2"
-
-
- For more information see HANDLING ERRORS.
-
- See also ErrorCode.
-
-
-
-
- SetLocF
- -----------------------------------------------------------------
-
- DECLARE SUB SetLocF (Handle%, NewPtrLoc&)
-
- Parameters: Handle% = handle of file whose ptr will be reset
- NewPtrLoc& = new location of pointer in the file
-
-
-
- SetLocF is a substitute for the statement form of SEEK. You
- pass it the handle of the file whose pointer you want to set and
- the location of the byte where you want to set the file pointer
- (as an offset from the start of the file):
-
-
- SetLocF Handle%, 9000&
-
-
- The above code moves the file pointer in the file designated by
- Handle% to byte number 9000. If subsequently you were to read
- from the file, byte 9000 would be the first byte read. If you
- were to write to the file, byte 9000 would be the first byte
- written to.
-
- If you are unfamiliar with file pointers, see ABOUT FILE
- POINTERS.
-
- How SetLocF interprets the value of NewPtrLoc& may vary,
- depending on whether you have made a call to SetPtrBase. By
- default, PBFiles considers the first byte of a file to be byte
- zero. However, you may change this default to a 1-based system,
- using SetPtrBase. Please see SetPtrBase for more details.
-
- It is possible to move the file pointer many bytes beyond the
- "end" byte of a disk file. This is a valid position at which to
- write to a disk file -- in which case the disk file will be
- extended to include all the bytes falling between the previous
- "end" of the file and the byte where the pointer was located
- when the writing was initiated.
-
- If you try to read from a file when the pointer is located
- beyond its end, then PBFiles will simply return with no action
- taken and no error code. If you try to read past the end byte
- of the file, PBFiles will read as far as the end byte of the
- file and stop.
-
- See also GetLocF.
-
-
-
-
- SetPtrBase
- -----------------------------------------------------------------
-
- DECLARE SUB SetPtrBase (PtrBase%)
-
- Parameters: PtrBase% = non-zero value sets pointer base to 1
-
-
-
- SetPtrBase sets the base value used by GetLocF& and SetLocF:
-
-
- SetPtrBase 1 'sets pointer base to 1
-
-
- Calling SetPtrBase with a zero sets the pointer base to zero.
- Calling SetPtrBase with any non-zero value sets the base value
- to 1. The default base value is zero.
-
- Normally, DOS defines the first byte of a file as byte 0 (zero).
- However, when Microsoft introduced BINARY file handling into
- BASIC, it chose to treat the first byte of a file as byte 1. To
- accomodate code written for this convention, PBFiles includes
- the commands SetPtrBase and GetPtrBase%.
-
- If you call SetPtrBase with a zero, PBFiles will act under the
- zero-based (DOS) convention. This is also the PBFiles default.
- Under this convention, when the pointer is at the second byte of
- a file, GetLocF& will return 1, and if you want to set the
- pointer to the second byte you would use SetLocF 1.
-
- If you call SetPtrBase with a non-zero value, PBFiles will act
- under the one-based (Microsoft BASIC) convention. Under this
- convention, when the pointer is at the second byte of a file,
- GetLocF& will return 2, and to set the pointer to the second
- byte you would use SetLocF 2.
-
- See also GetPtrBase.
-
-
-
-
- SizeF
- -----------------------------------------------------------------
-
- DECLARE FUNCTION SizeF& (Handle%)
-
- Parameters: Handle% = handle of file whose size you want
-
-
-
- SizeF& is a substitute for LOF. It returns the length of a file
- that has been opened with OpenF%, as a long integer:
-
-
- HowBig& = SizeF&(Handle%)
-
-
- In the above code, SizeF& returns the size of the file
- designated by Handle% and assigns the value to the variable
- HowBig&.
-
- If an error occurs, SizeF& returns a zero. Since zero is also a
- valid file length the only way to determine certainly if an
- error has occured is to call ErrorCode%.
-
-
-
- ********************************************************************
-
-
- WHY THIS FILE IS COPYRIGHTED
-
-
-
- Why is this file (PBFILES.DOC) copyrighted, while the source
- code file (PBFILES.ASM) is public domain?
-
- Simple. I decided to place the source code for PBFiles into the
- public domain to you and other PowerBASIC programmers a tool you
- could freely use, learn from, alter or improve and then
- incorporate in your programs without constraint. That is why
- PBFILES.ASM and PBFILES.OBJ are not copyrighted in any way.
-
- But I also wanted to retain some credit for the many hours of
- work PBFiles represents. The problem was how to attach a
- copyright to PBFiles without attaching a copyright specifically
- to the source code. The solution I reached was to copyright the
- documentation.
-
- The license which follows should not prevent you from using
- PBFiles in any legitimate way.
-
-
-
-
- LIMITED DISTRIBUTION LICENSE
-
-
- Brian McLaughlin (the "author"), grants to the holder (that's
- you) a limited license to copy, distribute or electronically
- transfer PBFILES.DOC (the "documentation") subject to the
- following terms and conditions:
-
- The documentation must be distributed whole and complete. You
- must not alter or modify the contents of the documentation in
- any way. Doing so will result in the immediate and automatic
- termination of this license.
-
- The documentation can only be distributed when accompanied by
- complete and unaltered copies of PBFILES.ASM, PBFILES.OBJ and
- PBFILES.BI (the "collateral files"). The copies of the
- collateral files which accompany the documentation must be
- identical to the collateral files which originally accompanied
- the documentation when it came into the possession of the
- license holder (you).
-
- Distribution of the documentation which fails to meet all these
- terms and conditions is prohibited and will result in immediate
- and automatic termination of this license.
-
-
- ──────────────────────────────────────────────────────────────────────
- Copyright 1994 Brian McLaughlin. All rights reserved.
-
-